package com.example.aigc_education.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.KgChatConversation;
import com.example.aigc_education.domain.vo.ChatConversationVO;
import com.example.aigc_education.enums.ChatConvStatus;
import com.example.aigc_education.integration.request.ChatMessageRequestV2;
import com.example.aigc_education.mapper.KgChatConversationMapper;
import com.example.aigc_education.service.KgChatConversationService;
import com.example.aigc_education.service.converter.KgChatConConverter;
import com.example.aigc_education.ws.handler.MessageHandler;
import com.example.aigc_education.ws.handler.MessageHandlerFactory;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 23918
* @description 针对表【kg_chat_conversation】的数据库操作Service实现
* @createDate 2025-03-17 11:29:36
*/
@Service
public class KgChatConversationServiceImpl extends ServiceImpl<KgChatConversationMapper, KgChatConversation>
    implements KgChatConversationService {
    @Autowired
    private KgChatConConverter kgChatConConverter;
    @GrpcClient("agent-algo-service")
    private com.example.aigc_education.rpc.api.v2.ChatServiceGrpc.ChatServiceBlockingStub chatServiceStubV2;



    @Override
    public List<ChatConversationVO> getUserChatHistoryList(Long userId) {
        try {
            LambdaQueryWrapper<KgChatConversation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(KgChatConversation::getUserId, userId);
            queryWrapper.ne(KgChatConversation::getConvStatus, ChatConvStatus.DELETE);
            queryWrapper.orderByDesc(KgChatConversation::getLastChatTime);
            List<KgChatConversation> kgChatConversations = this.list(queryWrapper);
            List<ChatConversationVO> chatConversationVOS = kgChatConConverter.kgChatConSToChatConVOS(kgChatConversations);
            return chatConversationVOS;
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("获取用户聊天记录列表失败");
        }

    }

    @Override
    public List<ChatMessageRequestV2> getAILAChatHistory(Long userId, Long convId) {
        try {
            com.example.aigc_education.rpc.api.v2.ChatServiceProto.ChatMessage message = com.example.aigc_education.rpc.api.v2.ChatServiceProto.ChatMessage.newBuilder()
                    .setUserId(userId)   // 重要！用户id
                    .setConvId(convId)   // 重要！会话id
                    .build();       // 虽然 message 还可以有其他可以 set 的字段，但是由于其他字段对于获取历史记录没用，遂略去
            com.example.aigc_education.rpc.api.v2.ChatServiceProto.ChatMessageList messageList =
                    chatServiceStubV2.getHistory(message);

            List<ChatMessageRequestV2> responses = messageList.getMessageList().stream()
                    .map(item -> {
                        // 使用工厂获取适合的处理器并处理消息
                        MessageHandler handler = MessageHandlerFactory.getHandler(item);
                        // 由于这个工厂是专为 stream 消息设计的，且用户是有可能在消息的 contents 字段中一次性传递多个消息的，
                        // 这样的设计我暂时没有找到解决 `无法获取用户 text 类型消息的问题` 和 `无法处理用户多个消息输入的解析的问题` 的方法
                        return handler.handle(item);
                    }).collect(Collectors.toList());
            return responses;
        }catch(Exception e){
            e.printStackTrace();
            throw new BusinessException("获取AI聊天记录失败");
        }

    }

    /**
     * 删除聊天记录
     *
     * @param convIds 要删除的聊天记录的会话ID列表
     * @throws BusinessException 当删除聊天记录失败时抛出业务异常
     */
    @Override
    public void deleteChatHistory(List<Long> convIds) {
        try {
            // 创建Lambda更新包装器以构建更新条件和设置
            LambdaUpdateWrapper<KgChatConversation>  updateWrapper =  new LambdaUpdateWrapper<>();
            // 设置条件：根据会话ID列表构建IN条件
            updateWrapper.in(KgChatConversation::getConvId, convIds);
            // 设置更新内容：将聊天记录的状态设置为删除
            updateWrapper.set(KgChatConversation::getConvStatus, ChatConvStatus.DELETE.getValue());
            // 执行更新操作
            this.update(updateWrapper);
        }
        catch (Exception e){
            // 打印异常堆栈跟踪
            e.printStackTrace();
            // 抛出业务异常，表示删除聊天记录失败
            throw new BusinessException("删除聊天记录失败");
        }
    }

    /**
     * 清空用户聊天记录
     *
     * @param userId 用户ID，用于标识需要清空聊天记录的用户
     * @return 返回一个布尔值，表示是否成功更新聊天记录的状态
     *
     * 此方法通过更新数据库中指定用户的所有聊天记录状态为删除，以实现清空聊天记录的功能
     * 选择使用LambdaUpdateWrapper进行条件更新，以提高代码的可读性和易维护性
     * 当发生异常时，打印异常信息并抛出自定义异常，以通知调用者清空聊天记录操作失败
     */
    @Override
    public Boolean clearChatHistory(Long userId) {
        try {
            // 创建LambdaUpdateWrapper对象，用于构建更新条件
            LambdaUpdateWrapper<KgChatConversation>  updateWrapper =  new LambdaUpdateWrapper<>();
            // 设置更新条件：根据用户ID匹配聊天记录
            updateWrapper.eq(KgChatConversation::getUserId, userId);
            // 设置聊天记录状态为删除
            updateWrapper.set(KgChatConversation::getConvStatus, ChatConvStatus.DELETE.getValue());
            // 执行更新操作并返回结果
            return this.update(updateWrapper);
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
            // 抛出自定义异常，通知调用者操作失败
            throw new BusinessException("清空聊天记录失败");
        }
    }



}




